This page documents the releases of the PC-Phone USB Sync app, from newest to oldest:
The Play store notifies users about Android updates as usual. Check this page for PC updates, as well as change details for all platforms.
This release makes the Android version of this app free, just like all its PC versions. Its in-app and online docs have been updated accordingly, and its trial version has been removed from the Play store. Please ignore any vestiges of the trial app that may linger in app screenshots on this site.
Apart from doc updates for the change to free on Android, no other changes were made in this release. Prior users need not install this update, because it remains functionally the same as 1.2.0 on all platforms.
Please enjoy this free and ad-free local-sync app on your phones and PCs, and thanks to all who supported its early development.
After a year and a half as paid, the realities of the Play store are glaring. Due to audience expectations, apps on Play cannot expect many installs unless they are free, but free apps by themselves cannot generate revenue needed to fund app development, resources, and visibility.
The only recourses in this climate are ethically dubious and rude—the embedded ads, subscriptions, and pay walls that most of us have come to loathe. The net effect is a vicious circle perpetuated by both users and developers that degrades app quality and user experience, but enriches Play's owner.
If you want to change this, please consider supporting independent developers by paying for apps whenever possible. This developer is able to provide apps on a pro bono basis, but most developers cannot. Look at it this way: if you wouldn't want what you do for a living to be valued as free, why would you do so for the software you use?
Naturally, Play's paradigm is now deeply entrenched, and change will require broad cultural shifts among both app consumers and producers. But a fair-pay-for-fair-work model would be enormously better for everyone than the crass idioms that have become norms on Play.
The 1.2.0 release is for all platforms: Android, Windows, macOS, and Linux. Its new install packages bring each platform's app up to date with all the patches made after 1.1.0, and apply a new batch of both Android-only and all-platform upgrades:
Note that some of the adopted changes still don't apply to all platforms, and others may have different meanings elsewhere. Linux mount rules, for example, are just for Linux; and the check for unwritable install folders on Windows is really a check for unwritable admin-file folders on macOS, which saves these files outside its install folder (for more details, see the Data sections in App Packages).
Because this app's APP storage root allows you to keep general content in app-specific storage, however, these app backups might also upload potentially sensitive content without your knowledge. To protect your privacy, these covert uploads have been disabled in this release. In exchange, your Config settings won't be auto-restored on a new device, but these are few and trivial to redo manually.
This release improves this case by preventing a new action's logfile from being deleted when its action runs, and issuing a new cautionary popup when it notices that the latest logfile is not newest. If you see this popup, please confirm your device's date/time before more runs. This may reflect a normal and temporary skew for DST or time-zone change which you can safely ignore, but it may also alert you to a genuine settings issue on your phone or PC.
The new WATCH model makes such nonsensical states impossible. At the same time, it also better addresses the preceding point: if the topmost logfile is not the most recent because the host's date/time has been moved back, it also won't be the right file to watch, and users would have to scroll to find the current run's file. By always using the current run's log regardless of GUI selections, the new WATCH makes an entire set of usability issues go away. With this change, TAIL and OPEN in Logs use the GUI selection, but WATCH and EXPLORE do not.
/
or C:\
), even
though such paths aren't generally useful because they depend on install location.
Second, on Android, the app now makes its app-private (a.k.a. internal private)
storage off-limits;
this storage is not listed in folder
choosers
and has no valid use case, because it's not accessible to any other
app.
This release raises the app's version number, because it's being published for all platforms, and includes changes that may modify behavior on some of them. Please upgrade your app to this new release on all your devices for the best syncing experience.
Version 1.1.0 was updated multiple times after its June 2023 release. These updates had limited scope: they addressed issues that occurred only on the PC platforms on which they were released, and none were known to be relevant to the Android app which was not rebuilt for any of these mods.
Because these releases did not span all platforms, they were not assigned new version numbers (but were incorporated for all platforms in the later 1.2.0). The latest version of each platform's package includes all the modifications applied in the following list:
/dev
),
and anywhere in /media*
or /mnt*
.
The 1.1.0 release adds five new usability features; works around four glitches in the underlying GUI toolkit plus one general issue that cropped up after 1.0.0; and makes seven additional minor mods (plus later PC patches). It's numbered 1.1.0 instead of 1.0.1 because it includes both enhancements and fixes. All its changes are backward compatible with 1.0.0, and apply to all platforms except as noted. Click here or scroll for info on all the upgrades in 1.1.0:
The confirmation popups shown for Main-tab action taps now display the FROM and TO paths about to be operated on, to remind you of the actions' subjects. You don't need to cancel the dialog and check the Main tab to see these paths.
In addition, these popups label the new path displays with storage names shown in the folder choosers, in case you don't recall the name of the storage types that corresponds to physical paths. For example, the FROM folder's path display on all platforms takes the form:
FROM: (label) path...
Where label is the logical name of the drive or storage, and path... is the full physical path. This same format is used to show FROM and TO folders when they apply to the selected action, so you can verify your choices.
Less abstractly, a FROM or TO removable-drive path on Windows that
starts with D:\...
is shown in the confirmation popups as
(drivename)
plus D:\...
. Other Windows
paths may be labeled (PC)
or (ROOT)
, and the
popups on Android similarly add labels (PHONE)
,
(APP)
, or (drivename)
before the
full physical path (for a primer on paths, see
this).
For live examples of the new confirmation-dialog displays on Android and PCs, try the Android shots here and here, and the PC shots here and here. This has no impact on GUI operation or behavior, apart from providing useful cross-check info prior to launching actions.
The Logs tab now catches double and triple taps (or clicks) on logfile-name buttons, and automatically runs TAIL for double taps, and TAIL+OPEN for triple taps. These shortcuts display logfiles made by Main-tab actions, and work for touch screens, touch pads, and mice on all platforms.
While useful, this is just a convenience: you can still run both TAIL and OPEN as before, by tapping a logfile-name button to select, and then tapping TAIL or OPEN. Double and triple taps are an extra option that mimics behavior expected from file explorers, and may be deemed quicker by some users.
Special case: TAIL is never run for taps when WATCH is active and the TAIL button is disabled, because the text area is being used by WATCH. By contrast, OPEN is run for taps whether WATCH is active or not.
For ease, this app now parses out crucial summary details from action logfiles, and presents them in an info popup when Main-tab actions exit. Viewing logfiles on narrow phones may require scrolling or rotating to landscape, and the brief summary bits now shown in the info popup often suffice, especially when simply verifying SYNCs or comparing summary counts against runs on another device.
in fact, in many cases the new info-popup summaries can make it unnecessary to open logfiles at all. When SHOW and DIFF are run to check that two folder copies are the same, for example, the simple "No differences" summary line in the popup saves a logfile view and multiple taps. To see the popup in action, view screenshots here and here. The "No difference" messages look like this and this.
That being said, it's still often useful or required to view logfiles after action runs. Most actions' logfiles include important details not given in the popup's summary. Moreover, the new summary may alert you to errors listed in the logfile that warrant further exploration—look for a line like this and search the logfile for "*" for more details; or let you know that the summary cannot be extracted—look for a line like this which may or may not be due to run failure, but you should see the log either way.
This change is cross platform, convenience only, and backward compatible. Its only app-behavior impacts are to list more details on action exit, and use popup dialogs instead of toasts on Android for action-exit messages; they're now too big for a simple toast, and too useful to vanish in seconds.
In the prior release, this app used a tool in its software stack which caused the screen to always remain on while the app was being used on Android. This prevented screen timeouts, and could drain battery power if users didn't press the power button or navigate away from the app.
In 1.1.0, this is now switchable by the user: the Config tab has a new
toggle, Keep the screen on while using this app?
, which controls
this behavior. If toggled on, the screen stays on in the app as before;
if off, screen timeouts are allowed to turn the screen off in the app
per user display settings on the device. See the new Config tab screenshots
here,
here, and
here.
This new toggle defaults to on (timeouts disabled) both for backward compatibility, and because this app presents textual information in logfiles and popups that may take time to view; toggle it off and save your settings to enable screen timeouts permanently. Though less impactful, this new toggle also applies to screen savers on PCs: on means screen savers will not run while the app has focus, and off means they will.
As part of this change, this app now also better ensures that Main-tab actions will keep running on Android if the screen turns off due to either timeouts or power-button presses. It does so by using an Android partial wake lock during Main-tab actions to keep the CPU running, whether the screen is set to stay on or not. This new wake lock is held only while an action is in progress. The former screen-on scheme may reduce throttling too, but drains battery power needlessly, and won't apply if users switch to another app or press the power button.
Technical readers can find more details on Android wake locks here, here, and here. See also the discussion of app stops in Tech Notes.
The GUI's folder-path fields—in both the Main-tab's FROM and TO choices, and the folder chooser's path display—can now be scrolled horizontally on PCs by a grab-and-move gesture. To scroll, click in a path field's text and quickly move the cursor while holding down your mouse or touchpad button. To select text in these fields instead, click and hold longer before moving. These fields also support manual edits and copy/paste on all platforms.
This change applies only to PCs (Windows, macOS, and Linux). Android devices have always scrolled these fields with touch swipe gestures as usual, and similarly select with a longer press and move. While scrolling is useful on PCs too, their wider screens naturally makes it less vital.
The underlying GUI library cannot display text lines that are atypically long, and instead shows them as empty black boxes. This was first addressed in 1.0.0 by truncating lines at 512 characters, but this proved to be still too long in some rare cases. Just one blacked-out line has cropped up among thousands seen, but it can be glaring when it happens.
To fix, 1.1.0 drops the truncation limit to 400 characters instead of 512 for Logs-tab text. This is both tradeoff and guess: it sacrifices more TAIL and WATCH content, and the actual line-length limit is context-dependent. But blacked-out lines will be less likely.
The underlying GUI toolkit has a race condition (i.e., timing issue) in its code, which can cause an app crash due to an uncaught exception. This could be triggered by tapping a Logs-tab filename button after a new Main-tab action was started, but was exceedingly rare, and observed just once after both hundreds (or thousands) of taps, and months of actual usage.
To fix, 1.1.0 avoids the crash potential in full by mutating filename buttons before they are deleted, in a way that ensures that the GUI's perilous code will not be run. The mutation is not user visible, and is harmless to the GUI's behavior. For full technical details on the fix, tap the button below (JavaScript required).
In this app, logfile toggle buttons are deleted on tab switches to update the Logs tab's list for new folder contents. Deleting these buttons can naturally trigger GC, which runs the GUI's GC callback. As coded, the GUI's GC callback and button-tap handler both remove the same cached items, and assume the two operations will not overlap unexpectedly.
In the crash observed, however, the GUI's tap handler attempted to remove an item from a cache which had already been removed by the GUI's GC callback. The net effect triggered an uncaught exception deep in the GUI's code. Although the timing required to cause this is rare in the extreme, this could happen anytime users started a new action, switched to Logs, and tapped a logfile button, thereby interleaving GC with taps.
Until this is fixed in the GUI toolkit, setting toggle buttons'
group ID to a Python None
prior to deletion suffices
to avoid the rare but fatal app crashes.
This workaround is a coincidental artifact of the GUI's code,
and not by design; to encourage a more robust fix, the underlying
race-condition bug should also be reported to the Kivy project.
Editorial: this timing bug joins a host of other Kivy issues, including fatal memory explosion caused by TextInput caching, which required additional, excruciating workarounds in this app. While Kivy is an impressive tool that allows Python to be used for apps on Android, it very much needs polishing that would extend its reach beyond the most hardcore of developers.
The underlying GUI toolkit fills text displays so slowly on Android that the initial draw is glitchy and noticeable: text appears as a single one-character column, before being drawn in full. The app formerly worked around this lag in its Help and About tabs by delaying the setting of text content until the next GUI frame, but some info popups have enough text to cause a lag too, including the first-run screen.
To fix, 1.1.0 now extends the Help/About workaround to text in all info popups, including those shown on first run. This avoids lag on slower phones. The lag was most apparent on one older and slower test device (a 2018 Note 9), but may have been noticeable on lower-end phones in general. The workaround has no impact on faster phones.
The underling GUI toolkit runs an animation at the end of manual text scrolls, which keeps scrolling slowly for a few seconds. Unfortunately, the animation is not automatically cancelled when the app tries to automatically scroll the same widget to the bottom or left of text newly added by TAIL or WATCH.
The net result is noticeably glitchy: if a manual scroll's animation is still in progress, the app's auto-scrolls do nothing, and can leave the new text's display in an odd location. Worse, the new text may also begin its tenure by scrolling incorrectly as a continuation of the prior scroll's animation.
To fix, 1.1.0 uses a (wildly obscure) coding workaround to cancel a manual scroll in progress, so that auto-scrolls always position the view as intended. The glitch was arguably rare: it required a TAIL during the trailing animation of a manual text scroll, or a vertical scroll in the limited text of WATCH. Still, the fix avoids a visual glitch without harm.
On all platforms, this app now avoids GUI lags and hangs for drives that are mounted but inaccessible. This includes both network drives that have been disconnected on PCs, as well as USB drives on Android and elsewhere that have not finished mounting in full. Formerly, such drives could cause the app to pause in multiple contexts for a noticeable number of seconds—up to 15 for network drives on Windows, and roughly half as much in other cases.
To fix, 1.1.0 uses parallel threads with timeouts to run system calls that are prone to hang when drives are not accessible. This fully removes the app hangs (apart from a brief half-second wait), and has no other impact on the app's behavior. If a drive access times out, simply rerun your action to access the drive once it's available.
For more info on using network drives with this app, click the button below (JavaScript required).
Update: the February 2024 rerelease for Windows avoids additional hangs that could occur while navigating in the app's folder chooser. These hangs were rare and seen only on Windows, but cropped up when using a hang-prone camera. They also happened deep in the code of the folder-chooser widget (not in code of the app itself), but the app was able to prevent them by using a system-calls hook. The rerelease also shortened the hang timeout from 0.5 to 0.25 seconds to lessen GUI lag.
T_Drive
, and as path
\\readyshare\T_drive
instead of the mapped Z:\
.
Formerly, the drive letter was shown at first, but confusingly morphed into
UNC on any chooser tap (this reflects a recent
change
in the Python language's realpath
call used by the Kivy GUI).
By comparison, on macOS this server is smb://readyshare
,
named T_Drive
in the app, and with Finder automatically mounts
at path /Volumes/T_Drive
. On Linux, this server's manually
mounted path should be in either /media
or /mnt
for use in this app.
In 1.1.0, the Android trial app's name displays with a ": Trial" suffix in notifications to distinguish it from the full app. This mod is minor and trivial, because the two apps are unlikely to be used at the same time (and in fact shouldn't be used to run update actions in parallel unless content folders are disjoint). Also note that some other contexts treat the two apps' names the same on purpose; the logfiles folder, for example, ignores the trial version's suffix so that all logs show up in the same place.
On all platforms, this app now scales the sizes of some of its GUI components to the density of the host display. This makes some buttons larger at higher resolutions and smaller at lower resolutions, which in turn makes the GUI look similar across all devices. In terms of function, buttons are now easier to tap on higher-resolution phones, and lower-resolution screens avoid GUI blowup and allow more on-screen content. All screenshots reflect the new sizes.
This mod's effect will naturally vary per screen, and may be more noticeable on some than on others. It superseded an earlier 1.1.0 change that reduced the absolute pixel sizes of logfile buttons on PCs, but this was really just catering to specific low-resolution devices, and didn't address other buttons in the GUI (e.g., responses in popups, and storage types in choosers). Using density-scaled pixels is a much more universal solution. See also the later 1.1.0 PC window-size update.
On Linux, this app now searches for mounted storage in both
the /media/user
and /mnt
folders
(where user
is your user name). The former, used in 1.0.0,
is where automatically mounted storage appears, including USB drives.
The latter, new in 1.1.0, is often used for manual user mounts. This
distinction is somewhat subjective, but be sure to mount network drives
and other types of storage to one of these two folders for quick access
in this app.
Please note: this pertains only to drives listed as main storages at the
top of the app's folder-chooser
popup.
You can always navigate down from the ROOT folder, /
, to select
and use any folder on your Linux PC, but mounting in the prescribed locations
adds the drives to the popup's list, thereby making selection faster and easier.
Update: the February 2024 rerelease
of the Linux app now recognizes mounted drives anywhere in /media*
or /mnt*
, having a source of /dev
(for physical devices)
or a Windows drive letter (e.g., C:\
for
WSL2). Mounts in /media
no
longer must be in the user's subfolder, non-drive mounts are filtered
out by source, and unlabeled drives still
work.
As before, ROOT is a fallback for custom mounts.
For more info, see the Tech Note.
This app now disallows attempts to use its COPY action to copy a folder into any of the folder's own subfolders. If allowed, such copies would be recursive, and may loop until stopped only by the host platform's path-length limits.
The app formerly disallowed copying a folder into itself directly, but this not enough: copies are always recursive if TO is nested anywhere in FROM (technically, if the absolute path of TO begins with the absolute path of FROM). While this subfolder case seems unlikely to crop up except accidentally, the app now detects it and cancels the COPY with an info popup, to avoid loops (and storage-space explosions).
This app disables its UNDO button when SYNC rollbacks cannot be used, and reenables it when they can. In short, UNDO is precluded when TO is known to have no SYNC backups, and is allowed otherwise. Any change to the TO path reinstates UNDO until TO's backups status is known.
Formerly, it was possible to reenable UNDO while another action was running, by changing TO with manual edits or chooser selections. Though obscure, this made it theoretically possible to launch an UNDO in parallel with a running action, with potentially dire consequences. In 1.1.0, this unintended loophole has been closed: UNDO is never reenabled on TO changes until an action in progress finishes.
This release repairs an obscure coding snafu which caused the modification times of symlinks (only) to be ignored by the macOS app (only), and was triggered by using Python 3.10 for universal 2 binaries. Symlinks' values were still compared and propagated correctly, so this was a very minor regression, and too arcane to detail here. Symlinks themselves are atypical, and not recommended in cross-platform content copies per the Tech Note.
Though it has no user-visible impact on the app, the Logs tab has been optimized to reset its text's size only on changes to display width, not height. This reset is required to enable horizontal scrolls after PC resizes and phone rotations due to a GUI quirk. However, it is not required for height changes on PCs, and width changes suffice to catch rotations on phones (a perfectly square phone would violate this rule, but none is known to exist, and its rotations wouldn't be very useful in any event).
Per this usage note, this app's top-of-display tabs bar sometimes fails to redraw on Android devices after rotating to landscape (wide) orientation when the Android 12L+ taskbar is open. This is relatively rare, and can occur only on large-screen devices because it's triggered by the Android large-screen taskbar, but is obvious when it crops up. A simple rerotate restores the app's tabs bar, and the issue can be avoided by disabling the Android taskbar while running the app.
This glitch, seen only on a Samsung Fold4 to date, stems from an event-processing bug in the software stack below this app's GUI. In short, the graphics system sends incorrect sizes on rotation events, which in turn crops top-of-screen content like the app's tabs bar. The 1.1.0 project did not work around this, but did uncover reasons that prevent it from doing so, and should be reporting the underlying bug to spur a fix. For more in-depth coverage of the glitch, click the button below (JavaScript required):
Specifically, when rotates to landscape work, the app receives either just one event with correct viewport height (excluding the taskbar), or two events: one with incorrect height (including the taskbar), and then another with correct height (excluding the taskbar). In the two-event case, there's a momentary visual effect for the redraw from incorrect to correct sizes, but the GUI's tabs bar appears.
When landscape rotates fail, however, there is just one event with incorrect height (the height of the physical display, plus the height of the taskbar), and the tabs bar is drawn offscreen. Because the event with the correct height is never received, it's futile for the app to forcibly redraw the wrongly sized display, and impossible for the app to reset a correct size when none exists.
Importantly, this glitch is not unique to either this app or its tabs bar. In another Kivy app running on the same large-screen phone, a portion of a simple button at the top of the display is also occasionally clipped vertically when rotating to landscape with the Android taskbar open. Hence, the lack of correct-size events renders part of the Kivy display offscreen on landscape rotations; a top-of-display tabs bar like that in this app just happens to be lost in full.
If this analysis is correct, addressing this glitch requires a core-code fix in SDL2 or Kivy, and this bug should be reported in hope of a repair. Until then, a regrettable but rare user rerotate will have to suffice as workaround.
This first release is functionally complete, and has been verified to work on Androids 8 through 13, Windows 10 and 11, macOS Catalina+, and Linux Ubuntu.
Beyond its core utility, 1.0.0 includes workarounds for eighteen glitches in the underlying GUI toolkit (to be published elsewhere), and addresses multiple interoperability hurdles on supported platforms. While additional enhancements and repairs are normal and expected to appear over this app's lifetime, its 1.0.0 release is already robust and fully usable as is.
For more on the app on 1.0.0 and later, see its user guide.
Watch this page for news about future releases. For info on using the app in general, see the User Guide.